/*
* Copyright (C) Microsoft. All rights reserved.  
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not 
* use this file except in compliance with the License.  You may obtain a copy 
* of the License at http://www.apache.org/licenses/LICENSE-2.0  
* 
* THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
* WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
* MERCHANTABLITY OR NON-INFRINGEMENT. 
*
* See the Apache License, Version 2.0 for specific language governing 
* permissions and limitations under the License.
*
*/

#pragma once

#include <string>
#include <vector>
#include <db/db.h>

namespace ClassRoom
{

namespace s = test_wrappers::storage;

class StudentRecord
{
public:
    unsigned int id;
    std::wstring name;
    unsigned int mm;
    unsigned int dd;
    unsigned int yy;
    std::wstring hobbies;
    unsigned int score;
};

class StudentTable
{
public:
    StudentTable();

    void Initialize(
        const std::shared_ptr<s::db_jet_engine>& dbEngine
        );

    void InsertOrUpdate(
        const unsigned int& id,
        const std::wstring& name,
        const unsigned int& mm,
        const unsigned int& dd,
        const unsigned int& yy,
        const std::wstring& hobbies,
        const unsigned int& score
        );

    void UpdateImage(
        const unsigned int& id,
        s::binary_blob& image
        );

    void AppendNote(
        const unsigned int& id,
        s::binary_blob& newNote
        );

    void ReadAll(
        std::vector<StudentRecord>& records
        );

    void ReadById(
        const unsigned int& id,
        std::vector<StudentRecord>& records
        );

    void ReadImageById(
        const unsigned int& id,
        s::binary_blob& image
        );

    void ReadNotesById(
        const unsigned int& id,
        s::binary_blob& allNotes
        );

    void ReadByYear(
        const unsigned int& year,
        std::vector<StudentRecord>& records
        );

    void ReadByScore(
        const unsigned int& score,
        std::vector<StudentRecord>& records
        );

    void DeleteById(
        const unsigned int& id
        );

private:
    std::shared_ptr<s::db_jet_engine> _dbEngine;

    const static std::wstring _name;


    s::table_instance _tableInstance;

    // fields
    s::field_id_t<unsigned int> _idFieldId;
    s::field_id_t<std::wstring> _nameFieldId;
    s::field_id_t<unsigned int> _mmFieldId;
    s::field_id_t<unsigned int> _ddFieldId;
    s::field_id_t<unsigned int> _yyFieldId;
    s::field_id_t<std::wstring> _hobbiesFieldId;
    s::field_id_t<unsigned int> _scoreFieldId;
    s::field_id_t<s::binary_blob> _imageFieldId;
    s::field_id_t<s::binary_blob> _notesFieldId;

    // helpers
    bool IsNewRecord(
        const unsigned int& id
        );

    void PackResult(
        const s::table_instance& tableInstance,
        const std::vector<s::tuple_values>& readRows,
        std::vector<StudentRecord>& records
        );

};

}// ClassRoom